package com.ruoyi.web.core.service;

import com.google.protobuf.InvalidProtocolBufferException;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.net.constant.UdpConstants;
import com.ruoyi.net.domain.ElementAlarm;
import com.ruoyi.net.domain.NetElement;
import com.ruoyi.net.domain.SysAlarmInfo;
import com.ruoyi.net.service.IElementAlarmService;
import com.ruoyi.net.service.INetElementService;
import com.ruoyi.net.utils.Alarm;
import com.ruoyi.system.service.ISysDictTypeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import oshi.util.Util;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Service
public class UdpService {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    HashMap<String, ElementAlarm> elementAlarmMap = new HashMap<>();

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private INetElementService netElementService;

//    @Autowired
//    private ISysDictTypeService dictTypeService;

    @Autowired
    private IElementAlarmService alarmService;
    /*
        private static final String TARGET_IP = "10.20.1.44";
        private static final int PORT = 7889;
        private static final int UDP_BUFFER_SIZE = 1024;
        private static final long POLLING_INTERVAL = 5000; // 轮询间隔，单位：毫秒
        private static final int TIMEOUT = 2000; // 接收数据的超时时间，单位：毫秒
        */
    // 序列号  25 40
    private Byte sno = 0;

    public byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i + 1), 16));
        }
        return data;
    }

    /**
     * Hex字符串转byte
     *
     * @param inHex 待转换的Hex字符串
     * @return 转换后的byte
     */
    public byte hexToByte(String inHex) {
        return (byte) Integer.parseInt(inHex, 16);
    }

    /**
     * hex字符串转byte数组
     *
     * @param inHex 待转换的Hex字符串
     * @return 转换后的byte数组结果
     */
    public byte[] hexToByteArray(String inHex) {
        int hexlen = inHex.length();
        byte[] result;
        if (hexlen % 2 == 1) {
            //奇数
            hexlen++;
            result = new byte[(hexlen / 2)];
            inHex = "0" + inHex;
        } else {
            //偶数
            result = new byte[(hexlen / 2)];
        }
        int j = 0;
        for (int i = 0; i < hexlen; i += 2) {
            result[j] = hexToByte(inHex.substring(i, i + 2));
            j++;
        }
        return result;
    }

    /**
     * 实现UDP发送和接收
     */
    public void sendAndReceive(DatagramSocket socket) {
        Collection<String> keys = redisCache.keys(CacheConstants.NET_ELEMENT_KEY + "*");
        for (String key : keys) {
            NetElement netElement = netElementService.getCacheObject(key.replaceAll(CacheConstants.NET_ELEMENT_KEY, ""));
            if (netElement != null
                    && !"2".equalsIgnoreCase(netElement.getDelFlag())
                    && StringUtils.isNotEmpty(netElement.getIp())) {
                // 发送 UDP 数据包
                try {
                    pingDevice(netElement);
                    String status_count = redisCache.getCacheObject(CacheConstants.NET_ELEMENT_STATUS + netElement.getId());
                    // 设备未离线的情况下发送数据
                    if (!"0".equalsIgnoreCase(status_count.split(",")[0])) {
                        sendData1(socket, netElement.getIp());
                    }

//                    Util.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void receiveData1(DatagramSocket socket, Collection<String> keys) {
        // 接收数据
        byte[] receiveData = new byte[UdpConstants.UDP_BUFFER_SIZE];
        DatagramPacket receivePacket = new DatagramPacket(receiveData, UdpConstants.UDP_BUFFER_SIZE);

        NetElement targetNetElement = new NetElement();
        String targetIp = "";
        try {
            socket.receive(receivePacket);
//            logger.info("接收到的数据长度: " + receivePacket.getLength());
            // 数据头长度
            int headerLen = 28 + 21 + 21;
            // source ip
            InetAddress sourceAddress = receivePacket.getAddress();
            targetIp = sourceAddress.getHostAddress();
            // 接收到的数据长度
            int dataLen = receivePacket.getLength();
            // 处理接收到的数据
            byte[] receivedBytes = receivePacket.getData();

            // 收到数据改变网元网络状态
            // 接收到数据，0 网元离线 灰色；1：告警 红；2：正常 绿色；
            for (String key : keys) {
                NetElement netElement = netElementService.getCacheObject(key.replaceAll(CacheConstants.NET_ELEMENT_KEY, ""));
                if (netElement != null && targetIp.equals(netElement.getIp())) {
                    targetNetElement = netElement;
                    break;
                }
            }

            // 正常 2
            redisCache.setCacheObject(CacheConstants.NET_ELEMENT_STATUS + targetNetElement.getId(), "2,0");

            if (dataLen > headerLen) {
                // 判断是否JC0422 【28,29，30,31】、报警数据【64,65】
                if (receivedBytes[28] == (byte) 0x4a
                        && receivedBytes[29] == (byte) 0x43
                        && receivedBytes[30] == (byte) 0x04
                        && receivedBytes[31] == (byte) 0x22
                        && receivedBytes[64] == (byte) 0x00
                        && receivedBytes[65] == (byte) 0x0d) {
                    // 处理接收到的数据
                    byte[] rData = new byte[dataLen - headerLen];
                    // 从PB数据开始
                    System.arraycopy(receivedBytes, headerLen, rData, 0, dataLen - headerLen);
                    Alarm.NeAlarmHead neAlarmHead = Alarm.NeAlarmHead.parseFrom(rData);
//                    logger.info(neAlarmHead.toString());

                    // 报警 1
                    redisCache.setCacheObject(CacheConstants.NET_ELEMENT_STATUS + targetNetElement.getId(), "1,0");
                    // 告警解析入库
                    List<ElementAlarm> elementAlarmList = new ArrayList<>();
                    List<Alarm.AlarmItem> itemList = neAlarmHead.getBrdAlrm(0).getArmVectorList();
                    for (Alarm.AlarmItem alarmItem : itemList) {
                        ElementAlarm elementAlarm = new ElementAlarm();
//                        elementAlarm.setId(IdUtils.simpleUUID());
                        elementAlarm.setElementId(targetNetElement.getId());
//                                    elementAlarm.setName(netElement.getElementName());
                        int alarmCode = alarmItem.getArmValue(0).getCode();
                        String strAlarmCode = "未知";
                        if (alarmCode == 2163) {
                            strAlarmCode = "输入光信号丢失(RLOS)";
                        } else if (alarmCode == 1753) {
                            strAlarmCode = "光模块不在位(OTRX_ABSENT)";
                        } else if (alarmCode == 3054) {
                            strAlarmCode = "配置未保存(CFG NOT SAVE)";
                        } else if (alarmCode == 795) {
                            strAlarmCode = "输入光功率过低(IOP LOW)";
                        }
                        elementAlarm.setAlarmCode(alarmCode + ""); // 告警代码
                        elementAlarm.setName(strAlarmCode); // 名称
                        // 告警类别
                        elementAlarm.setAlarmType("设备告警");
                        // 附加信息
                        elementAlarm.setAddition(alarmItem.getLine().getNetworkCrossString());
                        elementAlarm.setLineNo(alarmItem.getLine().getTag() + ":" + alarmItem.getLine().getLocateSrcString() + ""); // 线路号
                        elementAlarm.setIp(targetIp);
                        elementAlarm.setProjectStatus(alarmItem.getArmValue(0).getStatus() + ""); // 告警状态 || 级别
                        elementAlarm.setCreateBy("admin");
                        elementAlarm.setCreateTime(new Date(alarmItem.getArmValue(0).getTime() * 1000L));
                        elementAlarm.setUpdateBy("admin");
                        elementAlarm.setUpdateTime(elementAlarm.getCreateTime());
                        elementAlarmList.add(elementAlarm);
                    }
                    if (elementAlarmList.size() > 0) {
                        alarmService.insertElementAlarms(elementAlarmList);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("接收数据超时或出现异常: " + e.getMessage());
        } finally {
            // 更新网元显示状态
            if (StringUtils.isNotEmpty(targetNetElement.getId())) {
                String status_count = redisCache.getCacheObject(CacheConstants.NET_ELEMENT_STATUS + targetNetElement.getId());
                targetNetElement.setDisplayStatus(status_count.split(",")[0]);
                netElementService.updateElementStatus(targetNetElement);
//                netElementService.updateNetElement(targetNetElement);
            }
        }
    }

    /**
     * 合并byte数组
     */
    public byte[] unitByteArray(byte[] tbyte1, byte[] tbyte2) {
        byte[] unitByte = new byte[tbyte1.length + tbyte2.length];
        System.arraycopy(tbyte1, 0, unitByte, 0, tbyte1.length);
        System.arraycopy(tbyte2, 0, unitByte, tbyte1.length, tbyte2.length);
        return unitByte;
    }

    /**
     * 接收数据
     *
     * @param socket
     */
    public void receiveData(DatagramSocket socket) {
        Collection<String> keys = redisCache.keys(CacheConstants.NET_ELEMENT_KEY + "*");
        // 接收数据，创建一个数据接收缓冲区
        byte[] receiveData = new byte[UdpConstants.UDP_BUFFER_SIZE * 2];
        // 数据头长度
        int headerLen = 28 + 21 + 21;
        // 分段2 头部
        int headerLen2 = 12;
        byte[] part1 = null;
        byte[] part2 = null;
        while (true) {
            if (elementAlarmMap.size() > 100) {
                elementAlarmMap.clear();
            }
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

            NetElement targetNetElement = new NetElement();
            String targetIp = "";
            try {
                socket.receive(receivePacket);
//                logger.info("接收到的数据长度: " + receivePacket.getLength());
                // source ip
                InetAddress sourceAddress = receivePacket.getAddress();
                targetIp = sourceAddress.getHostAddress();
                // 接收到的数据长度
                int dataLen = receivePacket.getLength();
                // 处理接收到的数据
                byte[] receivedBytes = receivePacket.getData();

                // 收到数据改变网元网络状态
                // 接收到数据，0 网元离线 灰色；1：告警 红；2：正常 绿色；
                for (String key : keys) {
                    NetElement netElement = netElementService.getCacheObject(key.replaceAll(CacheConstants.NET_ELEMENT_KEY, ""));
                    if (netElement != null && targetIp.equals(netElement.getIp())) {
                        targetNetElement = netElement;
                        break;
                    }
                }
                if (StringUtils.isEmpty(targetNetElement.getId())) {
                    logger.info("未找到对应的网元, ip：" + targetIp);
                    // 更新缓存
                    netElementService.resetConfigCache();
                    keys = redisCache.keys(CacheConstants.NET_ELEMENT_KEY + "*");
                    continue;
                }

                // 正常 2
                redisCache.setCacheObject(CacheConstants.NET_ELEMENT_STATUS + targetNetElement.getId(), "2,0");

                // part1
                if (receivedBytes[5] != receivedBytes[7] && receivedBytes[7] > (byte) 0x01) {

                    part1 = new byte[dataLen];
                    System.arraycopy(receivedBytes, 0, part1, 0, dataLen);
                    continue;
                }
                else if (part1 != null && receivedBytes[5] == receivedBytes[7] && part1[3] == receivedBytes[3]) {

                    part2 = new byte[dataLen - headerLen2];
                    System.arraycopy(receivedBytes, headerLen2, part2, 0, part2.length);
                    // 合并
                    receivedBytes = unitByteArray(part1, part2);
                    dataLen = part1.length + part2.length;
                }

                if (dataLen > headerLen) {
                    // 判断是否JC0422 【28,29，30,31】、报警数据【64,65】
                    if (receivedBytes[28] == (byte) 0x4a
                            && receivedBytes[29] == (byte) 0x43
                            && receivedBytes[30] == (byte) 0x04
                            && receivedBytes[31] == (byte) 0x22
                            && receivedBytes[64] == (byte) 0x00
                            && receivedBytes[65] == (byte) 0x0d) {
                        // 处理接收到的数据
                        byte[] rData = new byte[dataLen - headerLen];
                        // 从PB数据开始
                        System.arraycopy(receivedBytes, headerLen, rData, 0, rData.length);
                        Alarm.NeAlarmHead neAlarmHead = Alarm.NeAlarmHead.parseFrom(rData);
//                        logger.info(neAlarmHead.toString());
                        part1 = null;
                        part2 = null;

                        // 报警 1
                        redisCache.setCacheObject(CacheConstants.NET_ELEMENT_STATUS + targetNetElement.getId(), "1,0");
                        // 告警解析入库
                        List<ElementAlarm> elementAlarmList = new ArrayList<>();
                        for (int i = 0; i< neAlarmHead.getBrdAlrmCount();i++) {
                            List<Alarm.AlarmItem> itemList = neAlarmHead.getBrdAlrm(i).getArmVectorList();
                            for (Alarm.AlarmItem alarmItem : itemList) {
                                ElementAlarm elementAlarm = new ElementAlarm();
//                            elementAlarm.setId(IdUtils.simpleUUID());
                                elementAlarm.setElementId(targetNetElement.getId());
//                                    elementAlarm.setName(netElement.getElementName());
                                int alarmCode = alarmItem.getArmValue(0).getCode();
                                // teset
//                            elementAlarm.setStatus(alarmItem.getArmValue(0).getStatus() + "");

                                String strAlarmCode = "未知";
                                String strAlarmType = "环境告警";
                                String strAlarmLevel = "提示"; // 50紧急 55主要 60次要  70提示
                            /*List<SysDictData> alarmList = dictTypeService.selectDictDataByType(UdpConstants.DICT_ALARM_CODE);
                            for (SysDictData dictData : alarmList) {
                                if (alarmCode == Integer.parseInt(dictData.getDictValue())) {
                                    strAlarmCode = dictData.getDictLabel();
                                    break;
                                }
                            }*/
                                SysAlarmInfo alarmInfo = redisCache.getCacheObject(CacheConstants.ALARM_INFO_KEY + alarmCode);

                                if (alarmInfo != null) {
                                    strAlarmCode = alarmInfo.getAlarmCn();
                                    // 告警英文代码
                                    elementAlarm.seteName(alarmInfo.getAlarmEn());
                                    // 告警级别: 50紧急 55主要 60次要  70提示
                                    if ("50".equals(alarmInfo.getAlarmLevel())) {
                                        strAlarmLevel = "紧急";
                                    } else if ("55".equals(alarmInfo.getAlarmLevel())) {
                                        strAlarmLevel = "主要";
                                    } else if ("60".equals(alarmInfo.getAlarmLevel())) {
                                        strAlarmLevel = "次要";
                                    } else if ("70".equals(alarmInfo.getAlarmLevel())) {
                                        strAlarmLevel = "提示";
                                    }
                                    // 告警类别 告警业务类型: 0通信告警 1环境告警 2设备告警 3服务质量告警 4处理失败告警 5安全告警"
                                    if ("0".equals(alarmInfo.getAlarmBusType())) {
                                        strAlarmType = "通信告警";
                                    } else if ("1".equals(alarmInfo.getAlarmBusType())) {
                                        strAlarmType = "环境告警";
                                    } else if ("2".equals(alarmInfo.getAlarmBusType())) {
                                        strAlarmType = "设备告警";
                                    } else if ("3".equals(alarmInfo.getAlarmBusType())) {
                                        strAlarmType = "服务质量告警";
                                    } else if ("4".equals(alarmInfo.getAlarmBusType())) {
                                        strAlarmType = "处理失败告警";
                                    } else if ("5".equals(alarmInfo.getAlarmBusType())) {
                                        strAlarmType = "安全告警";
                                    }
                                }
                            /*if (alarmCode == 2163) {
                                strAlarmCode = "输入光信号丢失(RLOS)";
                            } else if (alarmCode == 1753) {
                                strAlarmCode = "光模块不在位(OTRX_ABSENT)";
                            } else if (alarmCode == 3054) {
                                strAlarmCode = "配置未保存(CFG NOT SAVE)";
                            } else if (alarmCode == 795) {
                                strAlarmCode = "输入光功率过低(IOP LOW)";
                            }*/
                                // 告警代码
                                elementAlarm.setAlarmCode(alarmCode + "");
                                elementAlarm.setName(strAlarmCode); // 名称
                                // 告警类别
                                elementAlarm.setAlarmType(strAlarmType);
                                // 附加信息
                                elementAlarm.setAddition(alarmItem.getLine().getNetworkCrossString());

                                String lineContent = alarmItem.getLine().getLocateSrcString().toString(); //new String(alarmItem.getLine().getLocateSrcString().toByteArray(), StandardCharsets.UTF_8)
                                elementAlarm.setLineNo(alarmItem.getLine().getTag() + ":" + lineContent); // 线路号
                                elementAlarm.setIp(targetIp);
                                // 告警状态 || 告警级别
                                elementAlarm.setProjectStatus(strAlarmLevel);
//                            elementAlarm.setProjectStatus(alarmItem.getArmValue(0).getStatus() + ""); // 告警状态 || 级别

                                // 新增获取盘端口
                                int portIndex = lineContent.replaceAll("\">", "").lastIndexOf("/");
                                if (lineContent.indexOf("if-name=") > 0) {
                                    elementAlarm.setDiskPort(lineContent.replaceAll("\">", "").substring(portIndex + 1));
                                }
                                elementAlarm.setCreateBy("admin");
                                elementAlarm.setCreateTime(new Date(alarmItem.getArmValue(0).getTime() * 1000L));
                                elementAlarm.setUpdateBy("admin");
//                                elementAlarm.setUpdateTime(elementAlarm.getCreateTime());
                                elementAlarm.setUpdateTime(DateUtils.getNowDate());

                                String tempMapKey = elementAlarm.getElementId() + "-" + elementAlarm.getAlarmCode() + "-" + elementAlarm.getDiskPort();// + "-" + DateUtils.parseDateToStr(DateUtils.YYYYMMDDHHMMSS, elementAlarm.getCreateTime());
                                // 状态为 1 表示告警消除
                                if (0 == alarmItem.getArmValue(0).getStatus()) {
                                    // 更新 为不可见
                                    elementAlarm.setDelFlag("2");
                                    elementAlarm.setClearTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, elementAlarm.getCreateTime()));
                                    elementAlarm.setClearStatus("已清除");
                                    alarmService.updateElementAlarmRemove(elementAlarm);
                                    if (elementAlarmMap.get(tempMapKey) != null) {
                                        elementAlarmMap.remove(tempMapKey);
                                    }
                                } else {
                                    if (elementAlarmMap.get(tempMapKey) == null) {
                                        alarmService.insertElementAlarm(elementAlarm);
                                    }
                                    elementAlarmMap.put(tempMapKey, elementAlarm);
                                }
                            }
                        }
                        // 更新网元显示状态
                        if (StringUtils.isNotEmpty(targetNetElement.getId())) {
                            String status_count = redisCache.getCacheObject(CacheConstants.NET_ELEMENT_STATUS + targetNetElement.getId());
                            targetNetElement.setDisplayStatus(status_count.split(",")[0]);
                            netElementService.updateElementStatus(targetNetElement);
//                    netElementService.updateNetElement(targetNetElement);
                        }
                    }
                }
            } catch (InvalidProtocolBufferException e) {
                logger.error("解析告警数据出现异常: {}", e.getMessage());
            } catch (IOException e) {
                logger.error("IOException: {}", e.getMessage());
            } catch (Exception e) {
                logger.error("Exception: {}", e.getMessage());
            }
            Util.sleep(500);
        }
    }

    /**
     * 发送数据（发送告警、性能、心跳，ping通后发送数据）
     *
     * @param socket
     * @param ip
     */
    private void sendData1(DatagramSocket socket, String ip) {
        try {
            InetAddress targetAddress = InetAddress.getByName(ip);
            // 要发送的数据
            if (sno == Byte.MAX_VALUE) {
                sno = Byte.MIN_VALUE;
            } else {
                sno = (byte) ((sno + 1) & 0xFF);
            }

            // 28 + 21 告警 JC0421 0x9,
            char[] bytes = {0x0, 0x0, 0x0, 0x4f, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x82, 0x46, 0x48, 0x4d, 0x50, 0x2, 0xe1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x72,
                    0x4a, 0x43, 0x4, 0x21, 0x88, 0x0, 0x31, 0x0, 0x0, 0x81, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d,
                    0x80, 0x1, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};

            ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
            for (int i = 0; i < bytes.length; i++) {
                if (i == 23 || i == 38) {
                    buffer.put(sno);
                } else {
                    buffer.put((byte) bytes[i]);
                }
            }
            buffer.flip();
            byte[] sendData = buffer.array();
            // fos 28
            // 协议头21字节
            // 15字节
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, targetAddress, UdpConstants.UDP_PORT);
            socket.send(sendPacket);
//            logger.info("告警数据已发送");
/*
            // 性能数据 28 fos私有协议 + 21协议头 ,  JC0421 0xe,
            char[] pmBytes = {0x0, 0x0, 0x0, 0x1c, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x64, 0x46, 0x48, 0x4d, 0x50, 0x2, 0xe1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x54
                    , 0x4a, 0x43, 0x4, 0x21, 0x88, 0x0, 0x31, 0x0, 0x0, 0x81, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f
                    , 0x80, 0x1, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x10, 0x0, 0x18, 0x80, 0x81, 0x4, 0x20, 0x1, 0x2a, 0x20, 0x8, 0x0, 0x10, 0x0, 0x18, 0xff, 0x1, 0x20, 0xcc, 0x99, 0xb3, 0xe6, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x1, 0x2a, 0xc, 0xa, 0xa, 0x8, 0x2, 0x10, 0x4, 0x1a, 0x4, 0xff, 0xff, 0xff, 0xff, 0x32, 0x2, 0x31, 0x37};
            ByteBuffer bufferPm = ByteBuffer.allocate(pmBytes.length);
            for (int i = 0; i < pmBytes.length; i++) {
                if (i == 23 || i == 38) {
                    bufferPm.put(sno);
                } else {
                    bufferPm.put((byte) pmBytes[i]);
                }
            }
            bufferPm.flip();
            byte[] sendDataPm = bufferPm.array();
            // fos 28
            // 协议头21字节
            // 15字节
            DatagramPacket sendPacketPm = new DatagramPacket(sendDataPm, sendDataPm.length, targetAddress, UdpConstants.UDP_PORT);
            socket.send(sendPacketPm);
            logger.info("性能数据已发送");*/
        } catch (Exception e) {
            logger.info("数据发送失败：" + e.getMessage());
        }
    }

    private boolean pingDevice(NetElement netElement) {
        int successCount = 0;
        try {
            InetAddress inetAddress = InetAddress.getByName(netElement.getIp());
            for (int i = 0; i < UdpConstants.PING_COUNT; i++) {
                if (!inetAddress.isReachable(UdpConstants.PING_TIMEOUT)) {
                    successCount++;
                }
            }
            // 更改为离线状态
            if (successCount >= UdpConstants.PING_COUNT) {
                redisCache.setCacheObject(CacheConstants.NET_ELEMENT_STATUS + netElement.getId(), "0,0");
                netElement.setDisplayStatus("0");
                // 更新网元状态
                netElementService.updateElementStatus(netElement);
                return false;
            }
            String status_count = redisCache.getCacheObject(CacheConstants.NET_ELEMENT_STATUS + netElement.getId());
            // 当前设备不是告警的情况下，更新状态未正常
            if (StringUtils.isEmpty(status_count) || !"1".equals(status_count.split(",")[0])) {
                redisCache.setCacheObject(CacheConstants.NET_ELEMENT_STATUS + netElement.getId(), "2,0");
                netElement.setDisplayStatus("2");
                // 更新网元状态
                netElementService.updateElementStatus(netElement);
            }
            return true;
        } catch (IOException e) {
            logger.error("Ping device {} error: {}", netElement.getIp(), e.getMessage());
            return false;
        }
    }
}